Міністерство освіти і науки України
Національний університет „Львівська політехніка”
Кафедра ЕОМ
Лабораторна робота №7
з курсу:
«Засоби системного прграмування»
на тему:«Багатомодульне програмування»
Варіант: №7
Вираз: X=A4/B2-C1*(D1+E2-K)
K=717
МЕТА РОБОТИ:
Оволодіти навиками створення багатомодульних програм. Засвоїти правила взаємодії різних модулів.
ТЕОРЕТИЧНІ ВІДОМОСТІ:
Багатомодульне програмування
При роботі на мові Асемблер під багатомодульним програмуванням розуміють процес написання кількох процедур, підпрограм, у різних вихідних файлах з подальшим їх об’єднанням на етапі лінкування. Таке доцільно робити, коли:
є необхідність компонування декількох програм написаних на різних мовах програмування (наприклад, для об’єднання потужності мов високого рівня та ефективності асемблера);
програма, написана у вигляді одного модуля, може виявитись завеликою для асемблювання;
окремі модулі можуть бути написані різними проектувальниками з метою подальшої інтеграції;
з причини великого розміру виконавчого модуля може виникнути необхідність перекриття окремих частин програми в процесі виконання.
Кожна програма асемблюється окремо і генерує власний унікальний об’єктний (OBJ) модуль. Програма компонувальник (LINK) як правило виконання починається з основної програми, яка викликає одну або декілька підпрограм. Підпрограми, в свою чергу, можуть задіювати інші підпрограми.
Виклик іншої програми зумовлює необхідність міжсегментного (довгого) виклику (CALL). Дана операція спочатку записує до стеку вміст регістру CS і заносить до цього регістру адресу іншого сегменту, потім записує до стеку значення регістру IP і заносить до цього регістру нову відносну адресу.
Таким чином, в стеку запам’ятовуються і адреса кодового сегменту, і зміщення для наступного повернення з підпрограми.
Наприклад, міжсегментний виклик (CALL) може складатись з такого об’єктного коду:
9A 0002 AF04
Машинний код для міжсегментного виклику CALL – 9A. При цьому команда CALL записує значення 0002 у вигляді 0200 до регістру IP, а значення 04AF – до регістру CS. Комбінація цих адрес вказує на першу виконувану команду у програмі, що викликається:
Кодовий сегмент
04AF0
Зміщення в IP
0200
Дійсна адреса
04CF0
При виході з процедури, що викликалась, міжсегментна команда REТ відновлює обидві адреси в регістрах CS і IP і, таким чином, передає управління на наступну після CALL команду.
Розглянемо, наприклад, основну програму MAINPROG та підпрограму, що викликається за допомогою міжсегментного виклику CALL - SUBPROG.
EXTRN SUBPROG : FAR
MAINPROG: .
CALL SUBPROG
....
PUBLIC SUBPROG
SUBPROG: .
....
RET
Команда CALL в основній програмі повинна “знати”, що програма, яка викликається, знаходиться поза межами даного сегменту. Директива EXTRN вказує асемблеру, що посилання на SUBPROG має атрибут FAR, тобто є визначеним в іншому асемблерному модулі. Оскільки сам асемблер не має можливості точно визначити такі посилання, він генерує пустий об’єктний код для наступного його заповнення при компонуванні:
9A 0000 ---- E
Підпрограма SUBPROG містить директиву PUBLIC, що вказує асемблеру і компонувальнику, що інший модуль повинен “знати” адресу SUBPROG. В результаті, після успішного асемблювання програм MAINPROG і SUBPROG в окремих об’єктних модулях, вони можуть бути скомпільовані наступним чином:
D:\HOME\TASM > tasm MAINPROG /l
D:\HOME\TASM > tasm SUBPROG /l
D:\HOME\TASM > tlink MAINPROG + SUBPROG
Компонувальник встановлює відповідності між адресами EXTRN в одному об’єктному модулі з адресами PUBLIC в іншому і заносить необхідні відносні адреси. Потім він об’єднує два об’єктних модуля в один виконавчий.
В разі неможливості розв’язати посилання компонувальник видає повідомлення про помилку.
Директива EXTRN має такий формат:
EXTRN ім’я : тип [, … ]
Можна призначити більше одного імені (до кінця рядка) або закодувати додаткові директиви EXTRN. В іншому асемблерному модулі відповідне ім’я повинно бути визначене і ідентифіковане як PUBLIC. ...